#include "BitmapFont.h"

#include "../../SGD Wrappers/SGD_GraphicsManager.h"
#include "../../SGD Wrappers/SGD_Geometry.h"
#include <ctype.h>
#include <cassert>
#include <fstream>

void BitmapFont::Initialize(char* imageName, char* fileName)
{
	m_hImage = SGD::GraphicsManager::GetInstance()->LoadTexture(
		imageName, { 255, 0, 0, 0 });

	m_cFirstChar = ' ';		// space
	m_bOnlyUppercase = false;

	std::ifstream fin;
	fin.open(fileName);

	if (fin.is_open())
	{
		int row, col, posX, posY, width, height;
		row = col = posX = posY = width = height = 0;

		while (true)
		{
			if (fin.eof())
				break;

			BitmapChar* letter = new BitmapChar;

			fin >> row >> col >> posX >> posY >> width >> height;

			fin.ignore(INT_MAX, '\n');

			letter->SetRow(row);
			letter->SetColumn(col);
			letter->SetPosX(posX);
			letter->SetPosY(posY);
			letter->SetWidth(width);
			letter->SetHeight(height);
			vecChars.push_back(letter);
			letter = nullptr;
		}

		fin.close();
	}
}

void BitmapFont::Terminate(void)
{
	// Unload the image
	SGD::GraphicsManager::GetInstance()->UnloadTexture(m_hImage);

	for (unsigned int i = 0; i < vecChars.size(); ++i)
	{
		delete vecChars[i];
	}

	vecChars.clear();
}


void BitmapFont::Render(const char* output, SGD::Point position,
	float scale, SGD::Color color) const
{
	if (output[0] == '\0'
		|| scale == 0.0f
		|| color.alpha == 0)
		return;


	float colStart = position.x;

	for (int i = 0; output[i]; i++)
	{
		char ch = output[i];

		int id = ch - m_cFirstChar;

		if (ch == ' ')
		{
			position.x += vecChars[id]->GetWidth() * scale;
			continue;
		}
		else if (ch == '\n')
		{
			position.y += (vecChars[id]->GetWidth()) * scale;
			position.x = colStart;
			continue;
		}
		else if (ch == '\t')
		{
			float pixels = position.x - colStart;

			int chars = int(pixels / (vecChars[id]->GetWidth() * scale));

			int spaces = 4 - (chars % 4);

			position.x += spaces * (vecChars[id]->GetWidth() * scale);
			continue;
		}

		if (m_bOnlyUppercase == true)
			ch = toupper(ch);

		SGD::Rectangle cell;
		cell.left = (float)vecChars[id]->GetPosX();
		cell.top = (float)vecChars[id]->GetPosY();
		cell.right = cell.left + (float)vecChars[id]->GetWidth();
		cell.bottom = cell.top + (float)vecChars[id]->GetHeight();

		SGD::GraphicsManager::GetInstance()->DrawTextureSection(
			m_hImage, position,
			cell, 0.0f, {},
			color, { scale, scale });


		position.x += (int)(vecChars[id]->GetWidth() * scale);
	}
}

void BitmapFont::Render(const wchar_t* output, SGD::Point position,
	float scale, SGD::Color color) const
{
	if (output[0] == L'\0'
		|| scale == 0.0f
		|| color.alpha == 0)
		return;

	float colStart = position.x;

	for (int i = 0; output[i]; i++)
	{
		char ch = (char)output[i];

		int id = ch - m_cFirstChar;

		if (ch == ' ')
		{
			position.x += vecChars[id]->GetWidth() * scale;
			continue;
		}
		else if (ch == '\n')
		{
			position.y += vecChars[id]->GetHeight() * scale;
			position.x = colStart;
			continue;
		}
		else if (ch == '\t')
		{
			float pixels = position.x - colStart;

			int chars = int(pixels / (vecChars[id]->GetWidth() * scale));

			int spaces = 4 - (chars % 4);

			position.x += spaces * (vecChars[id]->GetWidth() * scale);
			continue;
		}

		if (m_bOnlyUppercase == true)
			ch = toupper(ch);

		SGD::Rectangle cell;
		cell.left = (float)vecChars[id]->GetPosX();
		cell.top = (float)vecChars[id]->GetPosY();
		cell.right = cell.left + (float)vecChars[id]->GetWidth();
		cell.bottom = cell.top + (float)vecChars[id]->GetHeight();

		SGD::GraphicsManager::GetInstance()->DrawTextureSection(
			m_hImage, position,
			cell, 0.0f, {},
			color, { scale, scale });

		position.x += (int)(vecChars[id]->GetWidth() * scale);
	}
}

void BitmapFont::SetImage(SGD::HTexture img)
{
	m_hImage = img;
}

SGD::HTexture BitmapFont::GetImage()
{
	return m_hImage;
}
